package com.onpositive.data.serializer.writers;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import javaewah.EWAHCompressedBitmap;

public abstract class CollectionWriter<T> extends AbstractWriter<T>{
	
	public static final int INT_SIZE = 4 ;
	
	int size = 0 ;
	ArrayList<Integer> emptyCells_ = new ArrayList<Integer>();
	ArrayList<T>values=new ArrayList<T>();
	EWAHCompressedBitmap emptyCells = new EWAHCompressedBitmap();
	
	public CollectionWriter( Class<T> clazz) {
		super(clazz);
	}
	
	
	public void append(T obj) {
		
		if( obj == null ){
			emptyCells.set( size ) ;
			obj = defaultObject() ;
		}
		else	
			values.add(obj) ;
		
		size++ ;		
	}
	
	abstract protected T defaultObject() ;

	@Override
	protected void doSerialize()
	{
		super.writeIntToStream( 5 * INT_SIZE + getItemSize() * values.size() + INT_SIZE * emptyCells_.size() );// writerID + 4 int fields
		super.writeIntToStream( getItemSize() );
		super.writeIntToStream( values.size());
		
		writeEmptyCells();		
		
		for (T w:values)
			writeValue( w ) ;
	}


	private void writeEmptyCells()
	{
		ByteArrayOutputStream byteArrOS = new ByteArrayOutputStream() ;
		DataOutputStream OS = new DataOutputStream( byteArrOS ) ;
		try {
			emptyCells.serialize( OS ) ;
		} catch (IOException e) {
			e.printStackTrace();
		}
		byte[] bArr = byteArrOS.toByteArray() ;
		
		super.writeIntToStream( bArr.length );
		super.writeByteArrayToStream( bArr ) ;
	}

	protected abstract int getItemSize();

	protected abstract void writeValue( T w ) ;
}